import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QHBoxLayout, QListWidget, QPushButton, \
    QLineEdit, QProgressBar,QAbstractItemView,QFileDialog,QMessageBox
from PyQt6.QtCore import QThread,pyqtSignal
from moviepy import VideoFileClip,concatenate_videoclips
from proglog import ProgressBarLogger


class MainWindow(QWidget):  #继承QWidget
    def __init__(self, *args, **kwargs):  #self is default parameter;you can add other parameters;
        #*args is mean any parameters; *kwargs is mean any dictronary parameters;
        super().__init__()  #继承执行父类的构造函数
        self.setWindowTitle("合并视频")  #set window title;be overrides the title
        ###############################################
        self.resize(600, 400)
        layout = QVBoxLayout()
        label = QLabel("请添加需要合成的文件")
        layout.addWidget(label)

        #secend layout
        list_content = QHBoxLayout()  #创建一个水平布局,容纳列表和按钮
        self.list_path = QListWidget()  #创建一个列表
        # self.list_path.addItem("c:/test/1.mp4")
        # self.list_path.addItem("c:/test/2.mp4")

        self.list_path.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)#可以多选
        self.list_path.setDragDropMode(QListWidget.DragDropMode.InternalMove)#设置列表拖拽模式

        buttons = QVBoxLayout()  #创建一个垂直布局,容纳按钮
        self.open_button = QPushButton("打开")
        self.open_button.clicked.connect(self.add)
        self.delete_button = QPushButton("删除")
        self.delete_button.clicked.connect(self.delete)
        buttons.addWidget(self.open_button)
        buttons.addWidget(self.delete_button)
        buttons.addStretch(1)#添加一个占位符,占用其余空间,把前面的部分顶到头部

        list_content.addWidget(self.list_path)#把列表添加到水平布局中
        list_content.addLayout(buttons)#把按钮布局放到水平布局中

        layout.addLayout(list_content)#把secend layout put into layout

        #third layout
        self.save_path_label = QLabel("请选择合成文件保存位置:")
        layout.addWidget(self.save_path_label)

        #fourth layout
        output_layout = QHBoxLayout()
        self.output_lineEdit = QLineEdit()
        self.choise_button=QPushButton("选择")
        self.choise_button.clicked.connect(self.choise)
        output_layout.addWidget(self.output_lineEdit)
        output_layout.addWidget(self.choise_button)
        layout.addLayout(output_layout)

        #fifth layout
        self.merge_button = QPushButton("开始合并")
        self.merge_button.clicked.connect(self.merge)
        layout.addWidget(self.merge_button)

        #sixth layout
        self.progress_message=QLabel("进度:")
        #self.progress_label = QLabel("进度:")
        self.progress_bar = QProgressBar()
        self.progress_bar.setProperty("value",0)
        layout.addWidget(self.progress_message)
        layout.addWidget(self.progress_bar)

        self.setLayout(layout)
        ###############################################
        bg_color = kwargs.get('setbackgroundColor', None)
        if bg_color:
            self.setStyleSheet(f"background-color: {bg_color};")
        self.show()
    def add(self):
        #file_path, _ = QFileDialog.getOpenFileNames(self, "选择文件", "", "视频文件 (*.mp4 *.avi)")#_ mean is default parameter;
        #print(file_path)
        file_dialog = QFileDialog()
        files,_= file_dialog.getOpenFileNames(filter="视频文件 (*.mp4 *.avi)", directory="")
        #print(files)
        for file_path in files:
            self.list_path.addItem(file_path)
        #self.list_path.addItem(file_path)
        #self.list_path.addItem("c:/test/3.mp4")
    def delete(self):
        #print(self.list_path.selectedItems())
        if not self.list_path.selectedItems():
            return
        for item in self.list_path.selectedItems():
            #index=self.list_path.indexFromItem(item).row()
            #self.list_path.takeItem(index)
            print(item.text())
            self.list_path.takeItem(self.list_path.row(item))
    def choise(self):
        file_path,_ = QFileDialog.getSaveFileName(filter="视频文件 (*.mp4 *.avi)", directory="")
        #(file_path)
        self.output_lineEdit.setText(file_path)
    def merge(self):
        if self.list_path.count()<2:
            print("请添加需要合成的文件")
            QMessageBox.critical(self, "提示", "至少要有2个视频才能合并")
            return
        if not self.output_lineEdit.text():
            print("请选择保存位置")
            QMessageBox.critical(self, "提示", "请选择保存位置")
            return
        print("开始合并")
        videos=[]
        for index in range(self.list_path.count()):
            #print(self.list_path.item(index).text())
            item=self.list_path.item(index).text()
            videos.append(item)
        self.worker=Worker(videos,self.output_lineEdit)
        self.worker.message.connect(self.set_message)
        self.worker.progress.connect(self.set_progress)
        self.worker.finished.connect(self.finished)
        self.worker.start()
        if self.worker.isRunning():
            self.merge_button.setEnabled(False)
        #final_clip=concatenate_videoclips(videos)
        #final_clip.write_videofile(self.output_lineEdit.text(),audio_codec="aac",fps=30)
        print("结束合并")
    def set_message(self,message):
        self.progress_message.setText(message)
    def set_progress(self,value):
        self.progress_bar.setValue(value)
    def finished(self):
        #QMessageBox.information(self, "提示", "合并完成", QMessageBox.StandardButton.Yes)
        self.merge_button.setEnabled(True)

class Worker(QThread):
    message = pyqtSignal(str)
    progress = pyqtSignal(int)
    finished = pyqtSignal()
    def __init__(self,videos,save_path):
        super().__init__()
        self.videos=videos
        self.save_path=save_path
        pass
    def run(self):
        videos=[]
        for video in self.videos:
            videos.append(VideoFileClip(video))

        final_clip=concatenate_videoclips(videos)
        my_logger = MyLogger(self.message,self.progress)
        final_clip.write_videofile(self.save_path.text(),audio_codec="aac",fps=30,logger=my_logger)
        self.finished.emit()
class MyLogger(ProgressBarLogger):
    def __init__(self,message,progress):
        super(MyLogger,self).__init__()
        self.message=message
        self.progress=progress
    def callback(self,**kw):
        if 'message' in kw:
            #print(kw['message'])
            self.message.emit(kw['message']) #emit发射信号
        bars=self.state.get('bars')#条状图
        index=len(bars.values())-1#当前进度
        print(index)
        if index>-1:
            bar=list(bars.values())[index]
            progress=int(bar["index"]/bar["total"]*100)
            print(f'progress is:{progress}%')
            self.progress.emit(progress)

class QSSLoader:
    def load(self, qss_file_path):
        with open(qss_file_path, 'r') as f:
            return f.read()



import traceback
import sys

def except_hook(cls, exception, traceback):
    sys.__excepthook__(cls, exception, traceback)
    input("Press enter to exit...")  # 防止窗口立即关闭

sys.excepthook = except_hook

if __name__ == "__main__":
    #print(sys.argv) #['D:\\u\\test\\gitee\\pythonqt\\test1\\改造程序\\new_hello2.py'] print sys.argv;default is this file path.
    app = QApplication(sys.argv)  #get parameters from command line.
    w = MainWindow(setbackgroundColor="lightblue")  #use MainWindow created a window.
    style=QSSLoader().load(r"D:\U\test\gitee\pythonqt\test1\Merge_Video\style.qss")
    w.setStyleSheet(style)
    w.setWindowTitle("合并视频")
    w.show()  #显示窗口
    #app.exec()#运行程序

    sys.exit(app.exec())  #app.exec() is first stop,then out process

    #import time #test app end,but process is not stop.
    #for i in range(10):#genarate a dictionary
    #    print(i)
    #    time.sleep(1)
# app=QApplication([])
# window=QWidget(windowTitle="Hello World",)#创建一个窗口
# window.show()#显示窗口
# app.exec()#运行程序
